/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package domain;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Writer;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 *
 * @author ParaSait
 */
public class Utils {

    public static boolean isValidEmail(String email) {
        Pattern pattern = Pattern.compile("^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*@[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$");
        Matcher matcher = pattern.matcher(email);
        return matcher.matches();
    }
    
    public static String byteArrayToHex(byte[] a) {
        StringBuilder sb = new StringBuilder();
        for(byte b: a)
            sb.append(String.format("%02x", b&0xff));
        return sb.toString();
    }

    public static byte[] calculateFileHash(File file) {
        try {
            MessageDigest md = MessageDigest.getInstance("SHA1");
            FileInputStream stream = new FileInputStream(file);
            byte[] dataBytes = new byte[1024];
            int nread = 0;

            while ((nread = stream.read(dataBytes)) != -1) {
                md.update(dataBytes, 0, nread);
            }
            stream.close();

            byte[] mdbytes = md.digest();
            return mdbytes;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }

    private static HashMap<String, File> getFileMap(HashMap<String, File> fileMap, File root, File subdir) {
        File[] fileArray = subdir.listFiles();

        for (File file : fileArray) {
            System.out.println("   TRAVERSING: " + file.getAbsolutePath());
            if (!file.isDirectory()) {
                System.out.println("   IS A FILE: " + file.getAbsolutePath());
                fileMap.put(root.toURI().relativize(file.toURI()).getPath(), file);
                System.out.println("   KEYS:");
                for(String key : fileMap.keySet())
                    System.out.println("     - " + key);
            } else {
                System.out.println("   IS A DIR: " + file.getAbsolutePath());
                getFileMap(fileMap, root, file);
            }
        }

        return fileMap;
    }

    public static HashMap<String, File> getFileMap(File root) {
        return getFileMap(new HashMap<String, File>(), root, root);
    }
    
    public static File createFileAndEmptyParents(Path path, String root) throws IOException {
        Files.createDirectories(path.getParent());
        File file = new File(path.toUri());
        file.createNewFile();

        return file;
    }

    public static void deleteFileAndEmptyParents(Path path, String root) throws IOException {
        if (path == null || path.startsWith(root)) {
            return;
        }

        if (Files.isRegularFile(path)) {
            Files.deleteIfExists(path);
        } else if (Files.isDirectory(path)) {
            if (new File(path.toUri()).list().length == 0) {
                Files.delete(path);
            } else {
                return;
            }
        }

        deleteFileAndEmptyParents(path.getParent(), root);
    }
    
    public static long copyLarge(InputStream input, OutputStream output) throws IOException {
        byte[] buffer = new byte[3];
        long count = 0;
        int n = 0;
        while (-1 != (n = input.read(buffer))) {
            output.write(buffer, 0, n);
            count += n;
        }
        
        return count;
    }
    
    public static int copy(InputStream input, OutputStream output) throws IOException {
        long count = copyLarge(input, output);
        if (count > Integer.MAX_VALUE) {
            return -1;
        }
        
        return (int) count;
    }
}
